#!/usr/bin/env python
# encoding: utf-8

import urllib
import urllib2
import json

import unittest

import re


API_URL = "http://api.put.io/v1/"

# TODO: cogu metodu eklemedim, sadece files/list icin get/post callback, callbacksiz testi

class ApiServerTestCase(unittest.TestCase):

    def setUp(self):
        self.api_key = 'XXXXXX'
        self.secret  = 'XXXXXX'

    def tes_json(self):
        s = self.send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"parent_id":0, "limit":1, "offset":0} },
                      service="files",
                      method="list" )
        try:
          o = json.loads(s)
        except:
          self.fail('result is not json')
#
    def test_callback_function(self):
        s = self.send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"parent_id":0, "limit":1, "offset":0} },
                      service="files",
                      method="list", callback="fn" )

        if re.search('fn\((.*)\)', s):
          pass
        else:
          self.fail('result is not json-p')



    def test_get_request(self):

        s = self.send_with_get(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"parent_id":0, "limit":1, "offset":0} },
                      service="files",
                      method="list" )
#        print "=============================="
#        print s
#        print "=============================="
        
        try:
          o = json.loads(s)
        except:
          self.fail('result is not json')


    def test_get_request_callback(self):

        s = self.send_with_get(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"parent_id":0, "limit":1, "offset":0} },
                      service="files",
                      method="list", callback='fn' )
#        print "=============================="
#        print s
#        print "=============================="

        m = re.search('fn\((.*)\)', s)
        
        if m:
          o = json.loads(m.group(1))
        else:
          self.fail('result is not json-p')

#http://api.put.io/v1/files?method=list
#http://api.put.io/v1/files?method=create_dir
#http://api.put.io/v1/files?method=info
#http://api.put.io/v1/files?method=rename
#http://api.put.io/v1/files?method=move
#http://api.put.io/v1/files?method=delete
#http://api.put.io/v1/files?method=search
#http://api.put.io/v1/files?method=dirmap

    # tests create_dir, list, info, rename, move, delete
    def test_files_create_dir(self):

        o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"parent_id":0, "name":"api-test"} },
                      service="files",
                      method="create_dir" )
        
        self.created_id = o['response']['results'][0]['id']

        o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"parent_id":0, "limit":1, "offset":0} },
                      service="files",
                      method="list" )
                      
        if (o['response']['results'][0]['id'] != self.created_id):
          self.fail('wrong files')

        o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"id":self.created_id, "limit":1, "offset":0} },
                      service="files",
                      method="info" )
                      
        if (o['response']['results'][0]['id'] != self.created_id):
          self.fail('wrong files')

        o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"id":self.created_id, "name":"test-1234", "offset":0} },
                      service="files",
                      method="rename" )

        if (o['response']['results'][0]['id'] != self.created_id):
          self.fail('wrong files')

        o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"id":self.created_id, "limit":1, "offset":0} },
                      service="files",
                      method="info" )

        if (o['response']['results'][0]['name'] != "test-1234"):
          self.fail('wrong files')


        o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"parent_id":0, "name":"api-test-parent"} },
                      service="files",
                      method="create_dir" )
        self.parent_id = o['response']['results'][0]['id']

        o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"id":self.created_id, "parent_id": self.parent_id, "offset":0} },
                      service="files",
                      method="move" )

        o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"parent_id":self.parent_id, "limit":1, "offset":0} },
                      service="files",
                      method="list" )

        if (o['response']['results'][0]['id'] != self.created_id):
          self.fail('wrong files')

        o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"id":self.created_id} },
                      service="files",
                      method="delete" )

        o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"parent_id":self.parent_id, "limit":1, "offset":0} },
                      service="files",
                      method="list" )

        if (len(o['response']['results'])):
          self.fail('wrong files')


        o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"limit":1, "offset":0} },
                service="files",
                method="dirmap" )
        fnd = False
        for k in o['response']['results']['dirs']:
          if k['id'] == self.parent_id:
            fnd = True

        if not fnd:
          self.fail('created dir not found')
        


    def test_files_search(self):
      o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"query":"lost", "limit":1, "offset":0} },
        service="files",
        method="search" )

      if o['response']['results'][0]['name'].lower().find("lost") > -1:
        pass
      else:
        self.fail('search')


    #http://api.put.io/v1/user?method=info
    #http://api.put.io/v1/user?method=friends
    def test_user(self):
      o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"query":"lost", "limit":1, "offset":0} },
        service="user",
        method="info" )

      if o['response']['results'][0]['name'] != 'aybars.badur':
        self.fail('user info is wrong')

      o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"query":"lost", "limit":1, "offset":0} },
        service="user",
        method="friends" )

      if len(o['response']['results']) > 0:
        pass
      else:
        self.fail('users count is wrong')

    def test_transfers(self):

      url = 'http://www.mininova.org/get/3136788'

      o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"links":[url]} },
        service="transfers",
        method="add" )

      o = self._send(post_args={'api_secret': self.secret, "api_key": self.api_key, "params":{"links":[url]} },
        service="transfers",
        method="list" )
      
      if o['response']['results'][0]['name'] == 'In Guantanamo.h264-VODO.mp4':
        pass
      else:
        self.fail('not found in transfers')




    def _send(self, post_args, service, **args):
      
      s = self.send(post_args, service, **args)
      
      try:
        o = json.loads(s)
      except:
        self.fail('result is not json [ %s ]' % s)

      return o



    def send_with_get(self, post_args, service=None, **args):

      query = urllib.urlencode(args) 

#      t = []
#      for index in post_args.keys():
#        p = "%s" % post_args[index]
#        g = "%s=%s" % (index, urllib.quote_plus(p))
#        t.append(g)
#
#      query += '&'.join(t)

      req = {'request':json.dumps(post_args)}

      url = API_URL + service + '/?' + query + '&' + urllib.urlencode(req)

      request = urllib2.Request(url)

      u = urllib2.urlopen(request)
      data = u.read()
      u.close()

      return data



    def send(self, post_args=None, service=None, **args):
        """DICT to JSON TO APISERVER"""

        url = API_URL

        if service: url += service
        if args: url += "?" + urllib.urlencode(args)

        # print " PostArgs: %s Args: %s URL: %s" % (post_args, args, url)

        if post_args is not None:
            req = {'request':json.dumps(post_args)}
            request = urllib2.Request(url, urllib.urlencode(req))
        else:
            request = urllib2.Request(url)

        u = urllib2.urlopen(request)
        data = u.read()
        u.close()

        return data




if __name__ == '__main__':
    unittest.main()
